#ifndef _RPC_CONTROLLER_H_
#define _RPC_CONTROLLER_H_

#include <google/protobuf/service.h>
#include <google/protobuf/stubs/callback.h>
#include <stdint.h>
#include <string>
#include "fastrpc/fastio/net.hpp"

namespace fastrpc::rpc {

class FastRpcController : public google::protobuf::RpcController {
public:
    FastRpcController() {}
    ~FastRpcController() {}

    void Reset() {
        m_error_code = 0;
        m_error_info = "";
        m_msg_id = "";

        m_is_failed = false;
        m_is_canceled = false;

        m_local_addr;
        m_peer_addr;

        m_timeout = 1000;  // ms
    }

    bool Failed() const {
        return m_is_failed;
    }

    std::string ErrorText() const {
        return m_error_info;
    }

    void StartCancel() {
        m_is_canceled = true;
    }

    void SetFailed(const std::string& reason) {
        m_error_info = reason;
    }

    bool IsCanceled() const {
        return m_is_canceled;
    }

    void NotifyOnCancel(google::protobuf::Closure* callback) {
        // TODO:
    }

    void SetError(int32_t error_code, const std::string error_info) {
        m_error_code = error_code;
        m_error_info = error_info;
        m_is_failed = true;
    }

    int32_t GetErrorCode() {
        return m_error_code;
    }

    std::string GetErrorInfo() {
        return m_error_info;
    }

    void SetMsgId(const std::string& msg_id) {
        m_msg_id = msg_id;
    }

    std::string GetMsgId() {
        return m_msg_id;
    }

    void SetLocalAddr(fastrpc::net::SocketAddr addr) {
        m_local_addr = addr;
    }

    fastrpc::net::SocketAddr GetLocalAddr() {
        return m_local_addr;
    }

    void SetPeerAddr(fastrpc::net::SocketAddr addr) {
        m_peer_addr = addr;
    }

    fastrpc::net::SocketAddr GetPeerAddr() {
        return m_peer_addr;
    }

    void SetTimeout(int timeout) {
        m_timeout = timeout;
    }

    int GetTimeout() {
        return m_timeout;
    }

private:
    int32_t     m_error_code{0};
    std::string m_error_info;
    std::string m_msg_id;

    bool m_is_failed{false};
    bool m_is_canceled{false};

    fastrpc::net::SocketAddr m_local_addr;
    fastrpc::net::SocketAddr m_peer_addr;

    int m_timeout{1000};  // ms
};

}  // namespace fastrpc::rpc

#endif